package com.tdk.mybatisplus.demo.common.advice;



import com.tdk.mybatisplus.demo.common.entity.Result;
import com.tdk.mybatisplus.demo.common.entity.ResultEnum;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.fileupload.FileUploadBase;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.converter.HttpMessageConversionException;
import org.springframework.util.ObjectUtils;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import javax.validation.ConstraintViolationException;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * <p>
 * 异常处理类
 * </p>
 *
 * @author: taodingkai
 * @modified:
 * @since: 2022/08/08 19:49
 */
@RestControllerAdvice
@Slf4j
@ResponseBody
public class DefaultExceptionAdvice {

    /**
     * <p>
     * 参数校验异常
     * </p>
     *
     * @param exception
     * @return com.tdk.mybatisplus.demo.common.entity.Result<java.lang.Object>
     * @author: taodingkai
     * @since: 2022/08/08 18:07
     */
    @ExceptionHandler(value = {BindException.class, MethodArgumentNotValidException.class})
    public Result<Object> validationFormException(Exception exception) {
        String message = "";
        List<String> msgList = new ArrayList<>();
        BindingResult result = null;
        if (exception instanceof BindException) {
            result = ((BindException) exception).getBindingResult();
        }
        if (exception instanceof MethodArgumentNotValidException) {
            result = ((MethodArgumentNotValidException) exception).getBindingResult();
        }
        if (Objects.nonNull(result) && result.hasErrors()) {
            List<ObjectError> errors = result.getAllErrors();
            if (!ObjectUtils.isEmpty(errors)) {
                errors.forEach(p -> {
                    FieldError fieldError = (FieldError) p;
                    log.error("Data check failure : object{" + fieldError.getObjectName() + "},field{" + fieldError.getField()
                            + "},errorMessage{" + fieldError.getDefaultMessage() + "}");
                    msgList.add(fieldError.getDefaultMessage());
                });
                message = StringUtils.join(msgList.toArray(), ";");
            }
        }
        log.error("参数校验异常", exception);
        return Result.fail(org.springframework.util.StringUtils.hasText(message) ? message : "请填写正确信息", null);
    }

    /**
     * <p>
     * 参数类型转换异常
     * </p>
     *
     * @param exception
     * @return com.tdk.mybatisplus.demo.common.entity.Result<java.lang.Object>
     * @author: taodingkai
     * @since: 2022/08/08 18:06
     */
    @ExceptionHandler(HttpMessageConversionException.class)
    public Result<Object> parameterTypeException(HttpMessageConversionException exception) {
        log.error("参数类型转换异常", exception);
        return Result.fail("参数类型转换异常", null);

    }

    /**
     * <p>
     * 方法参数校验异常
     * </p>
     *
     * @param exception
     * @return com.tdk.mybatisplus.demo.common.entity.Result<java.lang.Integer>
     * @author: taodingkai
     * @since: 2022/08/08 18:05
     */
    @ExceptionHandler(value = ConstraintViolationException.class)
    public Result<Integer> constraintViolationException(Exception exception) {
        String message = "";
        if (exception.getMessage() != null) {
            int index = exception.getMessage().indexOf(":");
            message = index != -1 ? exception.getMessage().substring(index + 1).trim() : exception.getMessage();
        }
        log.error("方法参数校验异常", exception);
        return Result.fail(message, ResultEnum.FILE_OVERSIZE.getCode());
    }

    /**
     * <p>
     * 文件上传异常
     * </p>
     *
     * @param exception
     * @return com.tdk.mybatisplus.demo.common.entity.Result<java.lang.Integer>
     * @author: taodingkai
     * @since: 2022/08/08 18:05
     */
    @ExceptionHandler(FileUploadBase.FileSizeLimitExceededException.class)
    public Result<Integer> handleException(FileUploadBase.FileSizeLimitExceededException exception) {
        log.error("文件上传异常", exception);
        return Result.fail(ResultEnum.FILE_OVERSIZE.getMessage(), ResultEnum.FILE_OVERSIZE.getCode());
    }

    /**
     * <p>
     * 其它异常
     * </p>
     *
     * @param exception
     * @return com.tdk.mybatisplus.demo.common.entity.Result<java.lang.Exception>
     * @author: taodingkai
     * @since: 2022/08/08 18:06
     */
    @ExceptionHandler(value = Exception.class)
    public Result<Exception> handleOtherException(Exception exception) {
        log.error("内部错误", exception);
        return Result.fail(exception.getMessage(), null);
    }
}